package com.woniu.service;

import com.woniu.adapter.BuyRateAdapter;
import com.woniu.adapter.UserDetailAdapter;
import com.woniu.exception.UserException;
import com.woniu.inlet.fo.UserFo;
import com.woniu.inlet.vo.FixedDayVo;
import com.woniu.inlet.vo.FixedInputBuyOrder;
import com.woniu.inlet.vo.FixedMsgVo;
import com.woniu.inlet.vo.PayToOrderVo;
import com.woniu.outlet.client.OrderMessage;
import com.woniu.outlet.client.UpdateOrderStatus;
import com.woniu.outlet.mysql.po.BuyRateMySQL;
import com.woniu.service.bean.*;
import com.woniu.service.domain.UserDetail;
import com.woniu.util.AppUtils;
import com.woniu.util.DateUtil;
import com.woniu.util.IsWorkingDayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

@Service
@Slf4j
public class UserDetailService implements VerifyBalanceCommandHandler, PayCommandHandler {

    @Autowired
    private UserDetailAdapter userDetailAdapter;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private BuyRateAdapter buyRateAdapter;
    @Autowired
    private UpdateOrderStatus updateOrderStatus;
    @Autowired
    private OrderMessage orderMessage;

    /**
     * 支付
     *
     * @param payCommand
     * @return
     */
    @Override
    public boolean payMoney(PayCommand payCommand) throws UserException {
        UserFo userFo = payCommand.getUserFo();
        //比对幂等性token
        String s = stringRedisTemplate.opsForValue().get(userFo.getPayToken());
        log.debug("支付的幂等token为[{}]", s);
        if (s == null) {
            throw new UserException("请勿重复提交！！！");
        }

        UserDetail userDo = userDetailAdapter.getUserById(userFo.getId());

        if (userDo.getPayCount() < 1) {//支付次数不够
            boolean timeDifference = AppUtils.getTimeDifference(userDo.getPayTime());
            if (timeDifference == false) {//false ：小于30分钟
                throw new UserException("您已经支付五次失败，请稍后再试");
            } else {
                //重置支付次数
                userDo.setPayCount(5);
                userDetailAdapter.updateInfo(userDo);
            }
        }
        //判断密码是否正确
        if (!userDo.getPayPassword().equals(userFo.getPayPassword())) {//密码不正确
            userDo.setPayCount(userDo.getPayCount() - 1);
            userDo.setPayTime(AppUtils.getNowTimeStr());
            userDetailAdapter.updateInfo(userDo);
            log.debug("密码错误后，该用户剩余的支付次数[{}]", userDo.getPayCount());
            throw new UserException("您输入的支付密码有误");
        }
        //密码正确-->判断余额是否足够
        if (userDo.getRestAmount().compareTo(userFo.getPayMoney()) == -1) {
            userDo.setPayCount(5);
            userDo.setPayTime(AppUtils.getNowTimeStr());
            userDetailAdapter.updateInfo(userDo);
            throw new UserException("您的余额已不足，请及时冲值！！");
        }
        //更新余额
        userDo.setRestAmount(userDo.getRestAmount().subtract(userFo.getPayMoney()));

        userDo.setPayTime(AppUtils.getNowTimeStr());
        userDo.setPayCount(5);
        log.debug("支付成功的userDo对象是：[{}]", userDo);
        userDetailAdapter.updateInfo(userDo);

        //删除幂等性token
        stringRedisTemplate.delete(s);

        //生成用户交易记录
        AddBuyRecord addBuyRecord = new AddBuyRecord();
        addBuyRecord.setUserId(userFo.getId());
        addBuyRecord.setDealTime(AppUtils.getNowTimeStr());
        addBuyRecord.setDealPrice(userFo.getPayMoney());

        //判断是否为定期或者活期理财产品
        String productType = userFo.getProductType();
        if (productType.equals("fixed") || productType.equals("current")) {
            //定期活期产品不需要手续费
            addBuyRecord.setDealCharge(new BigDecimal(0));
            addBuyRecord.setProductType(userFo.getProductType());
            addBuyRecord.setProductCode(userFo.getCodeId());
        } else {
            //计算手续费
            BuyRateMySQL buyRate = buyRateAdapter.getBuyRateMSQLByMoney(userFo.getPayMoney());
            //手续费费率
            Double rate = buyRate.getRate();
            log.debug("手续费费率为{}", rate);
            //手续费
            BigDecimal cost = userFo.getPayMoney().multiply(new BigDecimal(rate.toString())).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
            log.debug("手续费为{}", cost);

            addBuyRecord.setDealCharge(cost); //手续费
            addBuyRecord.setProductType(userFo.getProductType()); //产品类型
            addBuyRecord.setProductCode(userFo.getCodeId());
        }

        //插入记录到用户交易记录
        int id = addBuyRecord.execute();//新插入数据id回填
        log.debug("存表之后id为：{}", id);

        //设置通知
        String inform = "";
        PayToOrderVo payToOrderVo = new PayToOrderVo();
        //为vo对象赋值 然后openfeign将vo对象传给订单模块
        if (userFo.getProductType().equals("fund") || userFo.getProductType().equals("gold")) {
            payToOrderVo.setPayId(id);
            payToOrderVo.setUserId(userFo.getId());
            payToOrderVo.setMoney(userFo.getPayMoney());
            payToOrderVo.setProductType(userFo.getProductType());
            payToOrderVo.setCodeId(userFo.getCodeId());
            payToOrderVo.setPayTime(AppUtils.getNowTimeStr());
            while (true) {
                try {
                    updateOrderStatus.buyFundOrGold(payToOrderVo);
                    break;
                } catch (Exception e) {
                    log.debug("失败，重试");
                }
            }

            //发消息给用户模块通知用户
            if (userFo.getProductType().equals("fund")) {
                inform = "您好，您购买的【基金】已提交，请等待确定。" + "-" + userFo.getId() + "-" + "y";
            } else {
                inform = "您好，您购买的【黄金】已提交，请等待确定。" + "-" + userFo.getId() + "-" + "y";
            }

        } else if (userFo.getProductType().equals("fixed") || userFo.getProductType().equals("current")) {
            payToOrderVo.setPayId(id);
            payToOrderVo.setUserId(userFo.getId());
            payToOrderVo.setMoney(userFo.getPayMoney());
            payToOrderVo.setProductType(userFo.getProductType());
            payToOrderVo.setCodeId(userFo.getCodeId());
            payToOrderVo.setRateOfReturn(userFo.getRateOfReturn());
            payToOrderVo.setFixedDay(userFo.getFixedDay()); //定期理财产品的时长，不是定期产品时长为0
            payToOrderVo.setName(userFo.getName()); //购买的产品名
            payToOrderVo.setPayTime(AppUtils.getNowTimeStr());
//            updateOrderStatus.buyFixedOrCurrent(payToOrderVo);
            while (true) {
                try {
                    updateOrderStatus.buyFixedOrCurrent(payToOrderVo);
                    break;
                } catch (Exception e) {
                    log.debug("失败，重试");
                }
            }

            //发消息给用户模块通知用户
            if (userFo.getProductType().equals("fixed")) {
                inform = "您好！您已成功购买的【定期产品】：" + userFo.getName() + "-" + userFo.getId() + "-" + "y";
            } else {
                inform = "您好！您已成功购买的【活期产品】：" + userFo.getName() + "-" + userFo.getId() + "-" + "y";
            }
        }
        orderMessage.sendMessage("pay.inform.user", "pay_inform_user", inform);
        return true;
    }

    /**
     * 验证余额是否充足
     *
     * @param command
     * @return
     */
    @Override
    public boolean verifyBalance(VerifyBalanceCommand command) {
        UserDetail userById = userDetailAdapter.getUserById(command.getId());
        log.debug("当前用户的可用余额为：{}", userById.getRestAmount());
        if (userById.getRestAmount().compareTo(command.getPayMoney()) > -1) {
            return true;
        }
        return false;
    }

    /**
     * 验证支付密码是否正确
     */
    public boolean verifyPayPassword(UserFo userFo) {
        UserDetail user = userDetailAdapter.getUserById(userFo.getId());
        if (user.getPayPassword().equals(userFo.getPayPassword()))
            return true;
        else
            return false;
    }

    /**
     * 修改支付密码
     *
     * @param userFo
     */
    public void updatePayPassword(UserFo userFo) {
        UserDetail user = userDetailAdapter.getUserById(userFo.getId());
        user.setPayPassword(userFo.getPayPassword());
        userDetailAdapter.updateInfo(user);
    }

    /**
     * 根据用户id获取
     *
     * @return
     */
    public UserDetail getMoneyByUserId(Integer userId) {
        return userDetailAdapter.getUserById(userId);
    }

    /**
     * 用户充值
     */
    public void userRecharge(UserFo userFo) {
        UserDetail user = userDetailAdapter.getUserById(userFo.getId());
        UserDetail userDetail = new UserDetail();
        userDetail.setRestAmount(user.getRestAmount().add(userFo.getRechargeAmount()));
        userDetail.setTotalAmount(user.getTotalAmount().add(userFo.getRechargeAmount()));
        userDetail.setUserId(user.getUserId());
        userDetailAdapter.updateInfo(userDetail);
    }

    /**
     * 添加新注册的用户到表中
     */
    public void addUser(UserDetail userDetail) {
        userDetailAdapter.addUser(userDetail);
    }

    /**
     * 跟新用户信息
     */
    public void updateUser(UserDetail userDetail) {
        userDetailAdapter.updateInfo(userDetail);
    }

    /**
     * 定投验证余额是否充足
     */
    public boolean isMoney(FixedMsgVo fixedMsgVo) {
        UserDetail user = userDetailAdapter.getUserById(fixedMsgVo.getUserId().intValue());
        if (user.getRestAmount().compareTo(new BigDecimal(fixedMsgVo.getFixedAmount())) >= 0) {
            //扣钱
            UserDetail userDetail = new UserDetail();
            userDetail.setRestAmount(user.getRestAmount().subtract(new BigDecimal(fixedMsgVo.getFixedAmount())));
            userDetail.setUserId(fixedMsgVo.getUserId().intValue());
            userDetailAdapter.updateInfo(userDetail);
            //发送通知给用户模块，告知定投已经续费成功
            String inform = "您好，您的定投产品" + fixedMsgVo.getName() + "已成功续费。" + "-" + fixedMsgVo.getUserId() + "-" + "y";
            orderMessage.sendMessage("pay.inform.user", "pay_inform_user", inform);
            AddBuyRecord addBuyRecord = new AddBuyRecord();
            addBuyRecord.setUserId(fixedMsgVo.getUserId().intValue());
            addBuyRecord.setDealTime(AppUtils.getNowTimeStr());
            addBuyRecord.setDealPrice(new BigDecimal(fixedMsgVo.getFixedAmount()));
            //定期没有手续费
            addBuyRecord.setDealCharge(new BigDecimal(0));
            addBuyRecord.setProductType(fixedMsgVo.getProductType());
            addBuyRecord.setProductCode(fixedMsgVo.getCodeId());
            int execute = addBuyRecord.execute();
            //openfeign给订单模块
            FixedInputBuyOrder fixedInputBuyOrder = new FixedInputBuyOrder();
            fixedInputBuyOrder.setPayId(execute);
            //计算可以买入的日期
            String sellTime = "";
            //得到当前系统时间
            String timeStr = AppUtils.getTime();
            //判断今天是否是工作日
            String isWorkingDay = IsWorkingDayUtil.getIsWorkingDay(timeStr);
            if(isWorkingDay.equals("y")){
                //获取当前系统时间的小时数
                String timeH = AppUtils.getTimeH();
                if(Integer.valueOf(timeH)<15){
                    //如果当天15点之前买入则当天可以出售
                    fixedInputBuyOrder.setRevocationTime(AppUtils.getTimeg());
                    sellTime = AppUtils.getTimeg();
                }else{
                    //否者就是当天15点之后买入的
                    String time = DateUtil.getIncomeDate();
                    fixedInputBuyOrder.setRevocationTime(time);
                    sellTime = time;
                }
            }else{
                //当天不是工作日
                String time = DateUtil.getIncomeDate();
                fixedInputBuyOrder.setRevocationTime(time);
                sellTime = time;
            }
            updateOrderStatus.fixedInputBuyOrder(fixedInputBuyOrder);
            return true;
        } else {
            //发送通知给用户模块，告知余额不足
            String inform = "您好，您购买的定投产品" + fixedMsgVo.getName() + "，订单支付时余额不足，请于14点之前充值，我们将为您再次创建订单。" + "-" + fixedMsgVo.getUserId() + "-" + "y";
            orderMessage.sendMessage("pay.inform.user", "pay_inform_user", inform);
            return false;
        }
    }

    /**
     * 定期产品的卖出
     */
    public void sellFixed(FixedDayVo fixedDayVo) {
        //跟新用户余额
        //根据用户id查询用户
        UserDetail user = userDetailAdapter.getUserById(fixedDayVo.getUserId().intValue());
        UserDetail userDetail = new UserDetail();
        userDetail.setUserId(user.getUserId());
        userDetail.setRestAmount(user.getRestAmount().add(fixedDayVo.getIncome()).add(fixedDayVo.getTotalPrincipal()));
        userDetail.setTotalAmount(user.getTotalAmount().add(fixedDayVo.getIncome()));
        userDetailAdapter.updateInfo(userDetail);
        //给用户发送消息
        String inform = "您好，你已成功卖出【定期】产品：" + fixedDayVo.getName() + "-" + fixedDayVo.getUserId() + "-" + "y";
        orderMessage.sendMessage("pay.inform.user", "pay_inform_user", inform);
        //向卖出记录表添加数据
        AddSellRecord addSellRecord = new AddSellRecord();
        addSellRecord.setUserId(fixedDayVo.getUserId().intValue());
        addSellRecord.setDealTime(AppUtils.getNowTimeStr());
        addSellRecord.setDealPrice(fixedDayVo.getIncome().add(fixedDayVo.getTotalPrincipal()));
        addSellRecord.setUserIncome(fixedDayVo.getIncome());
        //定期卖出不收手续费
        addSellRecord.setDealCharge(new BigDecimal(0));
        addSellRecord.setProductType(fixedDayVo.getProductType());
        addSellRecord.execute();
    }

    /**
     * 用户提现
     */
    public void getDeposit(UserFo userFo){
        //根据userid查询用户信息
        UserDetail user = userDetailAdapter.getUserById(userFo.getId());

    }
}
